#!/usr/bin/env python2
#-*- coding: utf-8 -*-

import sys
import hashlib
import random
import time

from Ump import utils
from Ump.common import exception

from Ump.objs.db import models
from Ump.objs.manager_base import Manager
from Ump.objs.token.manager import TokenManager
from Ump.objs.session_wrapper import enable_log_and_session,  _sw


def encode_passwd(plain_text):
    return hashlib.md5(plain_text.strip()).hexdigest()


@models.add_model(models.User)
class UserManager(Manager):

    def __init__(self):
        super(UserManager, self).__init__()
        self.tokenm = TokenManager()

    @enable_log_and_session(resource='user', event='create')
    def create(self, _logger, params):
        name = params.get('name')
        password = params.get('password')
        repnum = params.get('repnum')
        quota = params.get('quota')
        chap_name = params.get('chap_name')
        chap_password = params.get('chap_password')
        rolename = params.get('identity')
        protection_domain_ids = params.get('protection_domain_ids')
        if not chap_name:
            chap_name = name
            chap_password = name

        if models.User.query.filter_by(name=name).first():
            raise exception.AlreadyExists(name=name)

        _logger.update_props(oplog_obj=name)

        # TODO
        role = _sw.get_one(model=models.Role, id_or_spec={'name': rolename})
        pds = _sw.get_list_by_ids(models.ProtectionDomain, protection_domain_ids)
        values = {
            'name': name,
            'password': encode_passwd(password),
            'repnum': repnum,
            'quota': quota,
            'chap_name': chap_name,
            'chap_password': chap_password,
            'roles': [role],
            'protection_domains': pds,
        }

        user = models.User(values).save()
        return user

    @enable_log_and_session(resource='user', event='delete')
    def delete(self, _logger, params):
        user_id = params['id']

        user = models.User.query.filter_by(id=user_id).first()

        if not user:
            raise exception.UserNotFound(user_id=user_id)

        _logger.set_obj(user.name)
        verify_user_pool = models.Pool.query.filter_by(user_id=user.id).all()
        if verify_user_pool:
            raise exception.AuthenticationFailed('there is pool under the user so please delete pool precedence')
        else:
            return user.delete()

    @enable_log_and_session(resource='user', event='update')
    def update(self, _logger, params):
        user_id = params.get('id')

        repnum = params.get('repnum')
        quota = params.get('quota')
        chap_name = params.get('chap_name')
        chap_password = params.get('chap_password')
        protection_domain_ids = params.get('protection_domain_ids')
        user = models.User.query.filter_by(id=user_id).first()

        if not user:
            raise exception.UserNotFound(user_id=user_id)

        _logger.set_obj(user.name)

        values = {}
        if protection_domain_ids is not None:
            pds = _sw.get_list_by_ids(models.ProtectionDomain, protection_domain_ids)
            utils.update_values(values, 'protection_domains', pds, is_list=True)
        utils.update_values(values, 'repnum', repnum)
        utils.update_values(values, 'quota', quota)
        utils.update_values(values, 'chap_name', chap_name)
        utils.update_values(values, 'chap_password', chap_password)
        utils.update_values(values, 'protection_domains', None)
        user.update(values)
        return user

    @enable_log_and_session(resource='user', event='password')
    def password(self, _logger, params):
        user_id = params.get('id')
        name = params.get('username')
        user = models.User.query.filter_by(id=user_id).first()

        _logger.update_props(oplog_obj=user.name)

        password = params.get('password')
        newpassword = params.get('new_password')

        user = _sw.user_login(user.name, password)
        if not user:
            raise Exception(u'密码错误，请重新输入')

        values = {'password': encode_passwd(newpassword)}
        user.update(values)
        return user

    @enable_log_and_session(resource='user', event='login')
    def login(self, _logger, params):
        '''UI'user login with password or without.

        :param params: a dict, if without_password in params and True, 
        will not check password is right.
        '''
        username = params.get('username')
        password = params.get('password')

        _logger.set_obj(username)

        if params.get('without_password'):

            _logger.update_props(disable_oplog=True)

            user = _sw.get_user(username=username)

            token = self.tokenm._create_token_with_user(user)
        else:
            user = _sw.user_login(username, password)
            if not user:
                user = _sw.get_user(username=username)
                if not user:
                    tip = u'用户不存在，请重新输入'
                else:
                    tip = u'密码错误，请重新输入'
                raise Exception(tip)
            token = self.tokenm.create(params)
        return token



if __name__ == '__main__':
    pass
